/**
 * 轨迹图层类
 * 专注于轨迹展示与动画播放，支持轨迹线、关键点、播放控制等功能
 */

import { Map as OlMap } from 'ol';
import { Vector as VectorLayer } from 'ol/layer';
import { Vector as VectorSource } from 'ol/source';
import { Feature } from 'ol';
import { Point, LineString } from 'ol/geom';
import { BaseLayer } from './BaseLayer';
import { TrackLayerOptions, TrackPoint, Coordinate } from '../types';
import { StyleUtil } from '../utils/style';
import { DataUtil } from '../utils/data';
import { Style } from 'ol/style';

/**
 * 轨迹图层类
 */
export class TrackLayer extends BaseLayer {
  /** 图层配置 */
  protected options: TrackLayerOptions;
  /** 矢量数据源 */
  private source: VectorSource<Feature> | null = null;
  /** 轨迹线要素 */
  private trackLineFeature: Feature<LineString> | null = null;
  /** 关键点要素数组 */
  private keyPointFeatures: Feature<Point>[] = [];
  /** 起点要素 */
  private startPointFeature: Feature<Point> | null = null;
  /** 终点要素 */
  private endPointFeature: Feature<Point> | null = null;
  /** 当前播放位置索引 */
  private currentPlayIndex: number = 0;
  /** 播放定时器 */
  private playTimer: number | null = null;
  /** 动画帧ID */
  private animationFrameId: number | null = null;
  /** 是否正在播放 */
  private isPlaying: boolean = false;
  /** 轨迹点数据 */
  private trackPoints: TrackPoint[] = [];
  /** 动画点要素（播放时显示） */
  private animationPointFeature: Feature<Point> | null = null;
  /** 当前播放的插值位置（0-1） */
  private currentInterpolation: number = 0;
  /** 上次动画时间 */
  private lastAnimationTime: number = 0;

  /**
   * 构造函数
   * @param options 图层配置
   */
  constructor(options: TrackLayerOptions = {}) {
    super(options);
    this.options = {
      showKeyPoints: true,
      animationSpeed: 100,
      autoPlay: false,
      ...options
    };
  }

  /**
   * 创建图层
   */
  protected createLayer(): void {
    this.source = new VectorSource<Feature>();
    this.layer = new VectorLayer({
      source: this.source
    });
  }

  /**
   * 设置轨迹数据
   * @param trackPoints 轨迹点数组
   */
  setTrackData(trackPoints: TrackPoint[]): void {
    if (!this.source) {
      throw new Error('Layer not initialized');
    }

    this.trackPoints = trackPoints;
    this.clearTrack();

    if (trackPoints.length === 0) {
      return;
    }

    // 创建轨迹线
    this.trackLineFeature = DataUtil.createTrackLine(trackPoints);
    this.trackLineFeature.setStyle(this.options.lineStyle || StyleUtil.createLineStyle({
      color: '#3399CC',
      width: 3
    }));
    this.source.addFeature(this.trackLineFeature);

    // 创建起点
    if (trackPoints.length > 0) {
      this.startPointFeature = DataUtil.createPointFeature(trackPoints[0].coordinate);
      this.startPointFeature.setStyle(
        this.options.startPointStyle || StyleUtil.createCircleStyle({
          radius: 8,
          fillColor: '#00FF00',
          strokeColor: '#fff',
          strokeWidth: 2
        })
      );
      this.source.addFeature(this.startPointFeature);
    }

    // 创建终点
    if (trackPoints.length > 1) {
      this.endPointFeature = DataUtil.createPointFeature(trackPoints[trackPoints.length - 1].coordinate);
      this.endPointFeature.setStyle(
        this.options.endPointStyle || StyleUtil.createCircleStyle({
          radius: 8,
          fillColor: '#FF0000',
          strokeColor: '#fff',
          strokeWidth: 2
        })
      );
      this.source.addFeature(this.endPointFeature);
    }

    // 创建关键点（起点、终点、拐点）
    if (this.options.showKeyPoints && trackPoints.length > 2) {
      this.createKeyPoints(trackPoints);
    }

    // 创建动画点（使用更明显的图标样式）
    this.animationPointFeature = DataUtil.createPointFeature(trackPoints[0].coordinate);
    this.animationPointFeature.setStyle(
      StyleUtil.createIconStyle({
        src: 'data:image/svg+xml;base64,' + btoa(`
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
            <circle cx="12" cy="12" r="10" fill="#FFD700" stroke="#fff" stroke-width="2"/>
            <circle cx="12" cy="12" r="4" fill="#FF6B00"/>
            <path d="M12 2 L12 8 M12 16 L12 22 M2 12 L8 12 M16 12 L22 12" stroke="#fff" stroke-width="2"/>
          </svg>
        `),
        scale: 1,
        anchor: [0.5, 0.5],
        rotation: 0
      })
    );
    this.animationPointFeature.set('isAnimation', true);
    // 注意：Feature 没有 setZIndex 方法，通过样式控制层级
    this.source.addFeature(this.animationPointFeature);

    // 如果设置了自动播放，开始播放
    if (this.options.autoPlay) {
      this.play();
    }

    this.emit('trackchange', trackPoints);
  }

  /**
   * 创建关键点
   * @param trackPoints 轨迹点数组
   */
  private createKeyPoints(trackPoints: TrackPoint[]): void {
    if (!this.source) return;

    // 简化算法：检测拐点（角度变化较大的点）
    const keyPoints: TrackPoint[] = [trackPoints[0]]; // 起点

    for (let i = 1; i < trackPoints.length - 1; i++) {
      const prev = trackPoints[i - 1];
      const curr = trackPoints[i];
      const next = trackPoints[i + 1];

      // 计算角度变化
      const angle1 = Math.atan2(
        curr.coordinate[1] - prev.coordinate[1],
        curr.coordinate[0] - prev.coordinate[0]
      );
      const angle2 = Math.atan2(
        next.coordinate[1] - curr.coordinate[1],
        next.coordinate[0] - curr.coordinate[0]
      );

      const angleDiff = Math.abs(angle2 - angle1);
      const normalizedAngleDiff = Math.min(angleDiff, 2 * Math.PI - angleDiff);

      // 如果角度变化超过阈值（约30度），认为是关键点
      if (normalizedAngleDiff > Math.PI / 6) {
        keyPoints.push(curr);
      }
    }

    keyPoints.push(trackPoints[trackPoints.length - 1]); // 终点

    // 创建关键点要素
    this.keyPointFeatures = keyPoints.map(point => {
      const feature = DataUtil.createPointFeature(point.coordinate, point.properties);
      feature.setStyle(
        this.options.keyPointStyle || StyleUtil.createCircleStyle({
          radius: 6,
          fillColor: '#FFA500',
          strokeColor: '#fff',
          strokeWidth: 2
        })
      );
      feature.set('isKeyPoint', true);
      return feature;
    });

    this.source.addFeatures(this.keyPointFeatures);
  }

  /**
   * 清空轨迹
   */
  private clearTrack(): void {
    if (!this.source) return;

    this.source.clear();
    this.trackLineFeature = null;
    this.startPointFeature = null;
    this.endPointFeature = null;
    this.keyPointFeatures = [];
    this.animationPointFeature = null;
    this.currentPlayIndex = 0;
    this.stop();
  }

  /**
   * 播放轨迹动画（使用 requestAnimationFrame 实现流畅动画）
   */
  play(): void {
    if (this.isPlaying || this.trackPoints.length === 0) {
      return;
    }

    this.isPlaying = true;
    this.currentPlayIndex = 0;
    this.currentInterpolation = 0;
    this.lastAnimationTime = performance.now();
    this.emit('playstart');

    const animate = (currentTime: number) => {
      if (!this.isPlaying) {
        return;
      }

      const deltaTime = currentTime - this.lastAnimationTime;
      const speed = this.options.animationSpeed || 100; // 毫秒/点
      const progressIncrement = deltaTime / speed;

      // 计算总进度
      const totalPoints = this.trackPoints.length;
      if (totalPoints === 0) {
        this.stop();
        return;
      }

      this.currentInterpolation += progressIncrement;
      const totalProgress = this.currentInterpolation / (totalPoints - 1);

      if (totalProgress >= 1) {
        // 播放完成
        if (this.animationPointFeature && this.trackPoints.length > 0) {
          const lastPoint = this.trackPoints[this.trackPoints.length - 1];
          const geometry = this.animationPointFeature.getGeometry() as Point;
          geometry.setCoordinates(DataUtil.toOlCoordinate(lastPoint.coordinate));
        }
        this.stop();
        return;
      }

      // 计算当前点和下一个点
      const currentIndex = Math.floor(totalProgress * (totalPoints - 1));
      const nextIndex = Math.min(currentIndex + 1, totalPoints - 1);
      const segmentProgress = (totalProgress * (totalPoints - 1)) - currentIndex;

      const currentPoint = this.trackPoints[currentIndex];
      const nextPoint = this.trackPoints[nextIndex];

      // 插值计算当前位置
      const currentCoord = DataUtil.toOlCoordinate(currentPoint.coordinate);
      const nextCoord = DataUtil.toOlCoordinate(nextPoint.coordinate);
      
      const interpolatedCoord: [number, number] = [
        currentCoord[0] + (nextCoord[0] - currentCoord[0]) * segmentProgress,
        currentCoord[1] + (nextCoord[1] - currentCoord[1]) * segmentProgress
      ];

      // 计算方向角度（用于图标旋转）
      const angle = Math.atan2(
        nextCoord[1] - currentCoord[1],
        nextCoord[0] - currentCoord[0]
      );

      // 更新动画点位置和方向
      if (this.animationPointFeature) {
        const geometry = this.animationPointFeature.getGeometry() as Point;
        geometry.setCoordinates(interpolatedCoord);
        
        // 更新图标旋转角度（需要重新创建样式）
        const currentStyle = this.animationPointFeature.getStyle() as Style;
        if (currentStyle && currentStyle.getImage()) {
          const image = currentStyle.getImage() as any;
          if (image && image.getSrc) {
            const src = image.getSrc();
            const scale = image.getScale() || 1;
            const anchor = image.getAnchor() || [0.5, 0.5];
            const anchorXUnits = image.getAnchorXUnits() || 'fraction';
            const anchorYUnits = image.getAnchorYUnits() || 'fraction';
            const opacity = image.getOpacity() || 1;
            
            // 重新创建样式以更新旋转角度
            this.animationPointFeature.setStyle(
              StyleUtil.createIconStyle({
                src,
                scale,
                anchor,
                anchorXUnits,
                anchorYUnits,
                opacity,
                rotation: angle
              })
            );
          }
        }
      }

      // 更新当前索引
      if (currentIndex !== this.currentPlayIndex) {
        this.currentPlayIndex = currentIndex;
        this.emit('playprogress', {
          index: currentIndex,
          point: currentPoint,
          progress: totalProgress
        });
      }

      this.lastAnimationTime = currentTime;
      this.animationFrameId = requestAnimationFrame(animate);
    };

    this.animationFrameId = requestAnimationFrame(animate);
  }

  /**
   * 暂停播放
   */
  pause(): void {
    if (this.animationFrameId !== null) {
      cancelAnimationFrame(this.animationFrameId);
      this.animationFrameId = null;
    }
    if (this.playTimer !== null) {
      clearTimeout(this.playTimer);
      this.playTimer = null;
    }
    this.isPlaying = false;
    this.emit('playpause');
  }

  /**
   * 停止播放
   */
  stop(): void {
    if (this.animationFrameId !== null) {
      cancelAnimationFrame(this.animationFrameId);
      this.animationFrameId = null;
    }
    if (this.playTimer !== null) {
      clearTimeout(this.playTimer);
      this.playTimer = null;
    }
    this.isPlaying = false;
    this.currentPlayIndex = 0;
    this.currentInterpolation = 0;
    this.emit('playstop');
  }

  /**
   * 跳转到指定位置
   * @param index 位置索引
   */
  seekTo(index: number): void {
    if (index < 0 || index >= this.trackPoints.length) {
      return;
    }

    this.currentPlayIndex = index;
    const point = this.trackPoints[index];
    if (this.animationPointFeature) {
      const geometry = this.animationPointFeature.getGeometry() as Point;
      geometry.setCoordinates(DataUtil.toOlCoordinate(point.coordinate));
    }

    this.emit('playseek', {
      index,
      point
    });
  }

  /**
   * 设置播放速度
   * @param speed 速度（毫秒/点）
   */
  setAnimationSpeed(speed: number): void {
    this.options.animationSpeed = speed;
    if (this.isPlaying) {
      this.pause();
      this.play();
    }
  }

  /**
   * 获取播放状态
   * @returns 是否正在播放
   */
  getIsPlaying(): boolean {
    return this.isPlaying;
  }

  /**
   * 获取当前播放位置
   * @returns 位置索引
   */
  getCurrentPlayIndex(): number {
    return this.currentPlayIndex;
  }

  /**
   * 更新数据
   * @param trackPoints 轨迹点数组
   */
  updateData(trackPoints: TrackPoint[]): void {
    this.setTrackData(trackPoints);
  }

  /**
   * 销毁图层
   */
  destroy(): void {
    this.stop();
    super.destroy();
  }
}

